//@author A0105740R
package rightnow.parser.cmdline;

/**
 * This parser parses command type.
 */
final class CmdTypeParser {
	private static final int NUM_TOKEN_CMD_ONLY = 1;
	
	private static final String CMD_ADD_REGEX = "ad?d?";
	private static final String CMD_DEL_REGEX = "d(el(ete)?)?";
	private static final String CMD_EDIT_REGEX = "e(d(it)?)?";
	private static final String CMD_LIST_REGEX = "l(s|(ist))?";
	private static final String CMD_NOW_REGEX = "now";
	private static final String CMD_DONE_REGEX = "done";
	private static final String CMD_UNDONE_REGEX = "undone";
	private static final String CMD_PIN_REGEX = "pin";
	private static final String CMD_UNPIN_REGEX = "unpin";
	private static final String CMD_REDO_REGEX = "redo";
	private static final String CMD_UNDO_REGEX = "undo";
	private static final String CMD_NEXT_REGEX = "n(ext)?";
	private static final String CMD_PREV_REGEX = "p(rev(ious)?)?";
	private static final String CMD_PAGE_REGEX = "p(g|age)";
	
	/**
	 * 
	 * @param commandText != null
	 * @param numTokens 1 or 2
	 * @return parsed command type
	 * @throws CmdParserException
	 */
	public static CommandType parse(String commandText, int numTokens)
			throws CmdParserException {
		commandText = commandText.toLowerCase();
		if (commandText.isEmpty()) {
			throw new CmdParserException(CmdParserErrorMsg.ERROR_EMPTY_COMMAND);
		}
		else if (commandText.matches(CMD_ADD_REGEX)) {
			return CommandType.ADD;
		}
		else if (commandText.matches(CMD_DEL_REGEX)) {
			return CommandType.DELETE;
		}
		else if (commandText.matches(CMD_EDIT_REGEX)) {
			return CommandType.EDIT;
		}
		else if (commandText.matches(CMD_LIST_REGEX)) {
			if (numTokens == NUM_TOKEN_CMD_ONLY) {
				return CommandType.ALL;
			}
			else {
				return CommandType.SEARCH;
			}
		}
		else if (commandText.matches(CMD_NOW_REGEX)) {
			return CommandType.NOW;
		}
		else if (commandText.matches(CMD_DONE_REGEX)) {
			return CommandType.DONE;
		}
		else if (commandText.matches(CMD_UNDONE_REGEX)) {
			return CommandType.UNDONE;
		}
		else if (commandText.matches(CMD_PIN_REGEX)) {
			return CommandType.PIN;
		}
		else if (commandText.matches(CMD_UNPIN_REGEX)) {
			return CommandType.UNPIN;
		}
		else if (commandText.matches(CMD_REDO_REGEX)) {
			return CommandType.REDO;
		}
		else if (commandText.matches(CMD_UNDO_REGEX)) {
			return CommandType.UNDO;
		}
		else if (commandText.matches(CMD_NEXT_REGEX)) {
			return CommandType.NEXT;
		}
		else if (commandText.matches(CMD_PREV_REGEX)) {
			return CommandType.PREV;
		}
		else if (commandText.matches(CMD_PAGE_REGEX)) {
			return CommandType.PAGE;
		}
		else {
			throw new CmdParserException(
					String.format(
							CmdParserErrorMsg.ERROR_INVALID_COMMAND, commandText));
		}
	}
}
